package com.sample.rx3.ui

import android.os.Bundle
import android.util.Log
import androidx.activity.result.ActivityResultLauncher
import androidx.appcompat.app.AppCompatActivity
import com.google.gson.Gson
import com.loyal.client.RxConfig
import com.loyal.client.impl.RxSubscriberListener
import com.loyal.rx3.RxUtil
import com.sample.rx3.AndPerMission
import com.sample.rx3.MemoryUtil
import com.sample.rx3.databinding.ActivityMainBinding
import com.sample.rx3.ext.delayClick
import com.sample.rx3.ext.showSnackbar
import com.sample.rx3.libs.rxjava.RxProgressSubscriber
import okhttp3.OkHttpClient
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.concurrent.TimeUnit

class MainActivity : AppCompatActivity(), RxSubscriberListener<String?> {
    private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
    private val formatter = SimpleDateFormat("mm:ss", Locale.getDefault())
    private var singleLauncher: ActivityResultLauncher<String>? = null
    private var multipleLauncher: ActivityResultLauncher<Array<String>>? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)
        binding.login.setOnClickListener {
            it.delayClick()
            login()
        }
        binding.rxTimeout1.setOnClickListener {
            it.delayClick()
            rxTimeOut1()
        }
        binding.rxTimeout2.setOnClickListener {
            it.delayClick()
            rxTimeOut2()
        }
        binding.rxSingle.setOnClickListener {
            singleLauncher?.launch(AndPerMission.CAMERA)
        }
        singleLauncher = AndPerMission.single(this) {
            binding.root.showSnackbar("请求Camera权限<$it>")
            if (it) MemoryUtil.mkPkgDirs()
        }

        binding.rxMulti.setOnClickListener {
            multipleLauncher?.launch(MULTIPLE_PERMISSION)
        }
        multipleLauncher = AndPerMission.multiple(this) {
            if (it.isEmpty()) {
                binding.root.showSnackbar("已授权")
            } else
                binding.root.showSnackbar("请求权限被拒绝<$it>")
        }
    }

    private fun login() {
        binding.textLog.append("\n===================\n登录：开始=>\n")
        val config = RxConfig.getInstance()
        config.httpOrHttps = "https"
        config.url = "192.168.0.107"
        config.port = "9081"
        config.nameSpace = "mwm"
        binding.textLog.append("登录Config：$config\n")

        val current = System.currentTimeMillis()
        val subscriber = RxProgressSubscriber<String>(config)
        subscriber.withContext(this).setDialogMessage("loading...").showProgressDialog(true)
        subscriber.setTag(current)
        subscriber.setWhat(LOGIN).setSubscribeListener(this)
        val map = mutableMapOf<String, String>()
        map["account"] = "loyal"
        map["password"] = "loyal"
        RxUtil.rxExecute(subscriber.doLogin(Gson().toJson(map)), subscriber)
    }

    private fun rxTimeOut1() {
        binding.textLog.append("\n===================\n超时1：开始=>\n")
        val config = RxConfig.getInstance()
        config.httpOrHttps = "https"
        config.url = "192.168.0.107"
        config.port = "9080"
        config.nameSpace = "pospay"

        val ctBuilder = OkHttpClient.Builder()
        ctBuilder.readTimeout(12L, TimeUnit.SECONDS) //设置读取超时
        ctBuilder.writeTimeout(12L, TimeUnit.SECONDS) //设置写入超时
        ctBuilder.connectTimeout(12L, TimeUnit.SECONDS) //设置连接超时
        config.okCtBuilder = ctBuilder
        binding.textLog.append("超时1Config：$config\n")

        val current = System.currentTimeMillis()
        val subscriber = RxProgressSubscriber<String>(config)
        subscriber.setDialogMessage("loading...").showProgressDialog(false)
        subscriber.setTag(current)
        subscriber.setWhat(TIMEOUT1).setSubscribeListener(this)
        val map = mutableMapOf<String, String>()
        map["account"] = "loyal"
        map["password"] = "loyal"
        RxUtil.rxExecute(subscriber.doLogin(Gson().toJson(map)), subscriber)
    }

    private fun rxTimeOut2() {
        binding.textLog.append("\n===================\n超时2：开始=>\n")
        val config = RxConfig()
        config.httpOrHttps = "https"
        config.url = "192.168.0.155"
        config.nameSpace = "jtwf_self"
        val ctBuilder = OkHttpClient.Builder()
        ctBuilder.readTimeout(10L, TimeUnit.SECONDS) //设置读取超时
        ctBuilder.writeTimeout(10L, TimeUnit.SECONDS) //设置写入超时
        ctBuilder.connectTimeout(10L, TimeUnit.SECONDS) //设置连接超时
        config.okCtBuilder = ctBuilder
        binding.textLog.append("超时2Config：$config\n")

        val current = System.currentTimeMillis()
        val subscriber = RxProgressSubscriber<String>(config)
        subscriber.setDialogMessage("loading...").showProgressDialog(true)
        subscriber.setTag(current)
        subscriber.setWhat(TIMEOUT2).setSubscribeListener(this)
        val map = mutableMapOf<String, String>()
        map["account"] = "loyal"
        map["password"] = "loyal"
        RxUtil.rxExecute(subscriber.doLogin(Gson().toJson(map)), subscriber)
    }

    override fun onResult(what: Int, tag: Any?, result: String?) {
        val current = System.currentTimeMillis()
        val last = tag as? Long? ?: return
        val time = formatter.format(Date(current - last))
        when (what) {
            LOGIN -> binding.textLog.append("登录Result，用时：$time-{${result}}\n")
            TIMEOUT1 -> binding.textLog.append("超时1Result，用时：$time{${result}}\n")
            TIMEOUT2 -> binding.textLog.append("超时2Result，用时：$time{${result}}\n")
        }
    }

    override fun onError(what: Int, tag: Any?, e: Throwable) {
        val current = System.currentTimeMillis()
        val last = tag as? Long? ?: return
        val time = formatter.format(Date(current - last))
        when (what) {
            LOGIN -> binding.textLog.append("登录Error，用时：$time{${e.message}}\n")
            TIMEOUT1 -> binding.textLog.append("超时1Error，用时：$time{${e.message}}\n")
            TIMEOUT2 -> binding.textLog.append("超时2Error，用时：$time{${e.message}}\n")
        }
    }

    companion object {
        private const val LOGIN = 2
        private const val TIMEOUT1 = 4
        private const val TIMEOUT2 = 6
        private val MULTIPLE_PERMISSION = arrayOf(
            AndPerMission.ACCESS_COARSE_LOCATION,
            AndPerMission.ACCESS_FINE_LOCATION,
            AndPerMission.READ_PHONE_STATE
        )
    }
}